import React, {useEffect, useReducer} from "react";

/**
 * useReducer：
 *     1. useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer，
 *     并返回当前的 state 以及与其配套的 dispatch 方法。
 *     2. React 会确保 dispatch 函数的标识是稳定的，并且不会在组件重新渲染时改变。
 *
 * 适用场景：
 *     1.  state 逻辑较复杂且包含多个子值
 *     2. 下一个 state 依赖于之前的 state 等。
 *
 * 指定初始 state：
 *     1. 将初始 state 作为第二个参数传入 useReducer。
 *
 * 惰性初始化：
 *     1. 将 init 函数作为 useReducer 的第三个参数传入，这样初始 state 将被设置为 init(initialArg)。
 *     2. 用于计算 state 的逻辑提取到 reducer 外部，这也为将来对重置 state 的 action 做处理提供了便利。
 *
 * 跳过 dispatch：
 *     1. 如果 Reducer Hook 的返回值与当前 state 相同，React 将跳过子组件的渲染及副作用的执行。
 */
function init(initialCount) {
    return {count: initialCount};
}

const initialState = {count: 0};

function reducer(state, action) {
    switch (action.type) {
        case 'increment':
            return {count: state.count + 1};
        case 'decrement':
            return {count: state.count - 1};
        case 'no':
            return {count: state.count};
        default:
            throw new Error();
    }
}

export function HookTest4({initialCount}) {
    const [state, dispatch] = useReducer(reducer, initialState);
    const [state2, dispatch2] = useReducer(reducer, initialCount, init);

    useEffect(() => {
        dispatch({type: 'no'});
        console.log("11111");
    }, [dispatch]);

    useEffect(() => {
        console.log("22222");
    });

    return (
        <div>
            Count: {state.count}
            <button onClick={() => dispatch({type: 'increment'})}>+</button>
            <button onClick={() => dispatch({type: 'decrement'})}>-</button>
            <button onClick={() => dispatch({type: 'no'})}>不变</button>
            Count: {state2.count}
            <button onClick={() => dispatch2({type: 'increment'})}>+</button>
            <button onClick={() => dispatch2({type: 'decrement'})}>-</button>
        </div>
    );
}
